Function.RegisterNamespace("System.Script.ScriptLoadStrategy");

System.Script.ScriptLoadStrategy.Dom=function(){    
    // ILoadStrategy Members
    this.Import=function(path,callback){
        var script=document.createElement('script');
        var loadDelegate=Function.GetDelegate(Script_OnLoad,this,path,callback);
        var errorDelegate=Function.GetDelegate(Script_OnError,this,path,callback);
        Object.Set(script,{type:'text/javascript',onload:loadDelegate,onerror:errorDelegate,src:path});
        return document.body.appendChild(script);
    };
    
    this.ImportJson=function(path,callback){
        var target=document.createElement('iframe');
        var loadDelegate=Function.GetDelegate(Frame_OnLoad,this,path,callback,target);
        var errorDelegate=Function.GetDelegate(Frame_OnError,this,path,callback,target);
        Object.Set(script,{onload:loadDelegate,onerror:errorDelegate,src:path});
        document.body.appendChild(target);
    };   

    this.Load=function(source){
        var script=document.createElement('script');
        Object.Set(script,{type:'text/javascript',text:source});
        return document.body.appendChild(script);
    };
    
    // IStrategySpecification Members
    this.IsSatisfiedBy=function(candidate){
        return typeof(document)!='undefined';
    };
    
    // Events
    function Frame_OnLoad(path,callback,frame){
        frame.parentNode.removeChild(frame);
        var frameContent=frame.contentWindow.documentElement;
        var script=frameContent.textContent||frameContent.innerText;
        var serializer=new System.Script.ObjectSerializer();
        var result=serializer.Deserialize(String.Format("return false||({0})",script));
        if(callback)callback(path,result);
    }

    function Frame_OnError(path,callback,frame,error){
        frame.parentNode.removeChild(frame);
        var errorMessage=String.Format("System.Script.ScriptLoadStrategy.Dom.ImportJson: There was an error loading '{0}'. Error: {1}.",path,error||"Unknown");
        if(callback)callback(path,null,errorMessage);
        else throw new Error(errorMessage);        
    }
    
    function Script_OnLoad(path,callback){
        if(callback)callback(path);
    }

    function Script_OnError(path,callback,error){
        var errorMessage=String.Format("System.Script.ScriptLoadStrategy.Dom.ImportJson: There was an error loading '{0}'. Error: {1}.",path,error||"Unknown");
        if(callback)callback(path,errorMessage);
        else throw new Error(errorMessage);        
    }
};

System.Script.ScriptLoadStrategy.Dom.Implement(System.Script.ScriptLoadStrategy.ILoadStrategy,'System.Script.ScriptLoadStrategy.Dom');
System.Script.ScriptLoadStrategy.Dom.Implement(System.Script.Strategy.IStrategySpecification,'System.Script.ScriptLoadStrategy.Dom');

System.Script.ScriptLoader.Strategies.Add(System.Script.ScriptLoadStrategy.Dom);